package user

import (
	"errors"
	"github.com/xinliangnote/go-gin-api/internal/pkg/core"
	"github.com/xinliangnote/go-gin-api/internal/repository/mongodb/operation_log"
	"github.com/xinliangnote/go-gin-api/internal/repository/mongodb/user"
	userModel "github.com/xinliangnote/go-gin-api/internal/repository/mongodb/user"
	"github.com/xinliangnote/go-gin-api/internal/tools"
	"go.mongodb.org/mongo-driver/mongo"
	"time"
)

type LoginData struct {
	UserName string
	Password string
}

type PasswordData struct {
	UserId      string
	OldPassword string
	NewPassword string
}

type CreateData struct {
	Id           string
	UserName     string
	Password     string
	Email        string
	MaturityTime int64
	Remark       string
	LastLoginIP  string
}

func (s *service) Login(ctx core.Context, loginData *LoginData) (*user.User, error) {
	model := user.NewModel()
	model.Username = loginData.UserName
	model.Password = loginData.Password

	userData, err := model.GetUserByName(s.db.GetDb())
	if err != nil {
		return nil, errors.New("user is not exist")
	}
	md5Password := tools.MD5(model.Password)
	if userData.Password != md5Password {
		return nil, errors.New("password error")
	}
	if userData.Role != "1" {
		return nil, errors.New("not a super user")
	}
	return userData, nil
}

func (s *service) ChangePassword(ctx core.Context, passwordData *PasswordData) error {
	model := user.NewModel()
	model.Id = passwordData.UserId
	userInfo, err := model.GetUserById(s.db.GetDb())
	if err != nil {
		return errors.New("user is not exist")
	}

	oldMD5Password := tools.MD5(passwordData.OldPassword)
	if userInfo.Password != oldMD5Password {
		return errors.New("旧密码错误")
	}
	model.Password = tools.MD5(passwordData.NewPassword)
	err = model.ChangePassword(s.db.GetDb())
	return err
}

func (s *service) List(ctx core.Context, pageIndex uint, pageSize uint, username string, email string, status string) ([]*user.User, error) {
	model := user.NewModel()
	model.Username = username
	model.Email = email

	list, err := model.List(s.db.GetDb(), pageIndex, pageSize, status)
	return list, err
}

func (s *service) Count(ctx core.Context) (int64, error) {
	model := user.NewModel()
	count, err := model.Count(s.db.GetDb())
	return count, err
}

func (s *service) ChangeStatus(ctx core.Context, userId string, status int) error {
	model := user.NewModel()
	model.Id = userId
	model.Status = status
	err := model.ChangeStatus(s.db.GetDb())

	if err == nil {
		userInfo := ctx.GetInfo("userInfo").(*userModel.User)
		logModel := operation_log.NewModel()
		logModel.FTable = "user"
		logModel.Type = "edit"
		logModel.FId = userId
		logModel.IpAddr = ctx.GetClientIP()
		logModel.AdminName = userInfo.Username
		logModel.Content = "更新用户状态:状态[" + string(rune(status)) + "]"
		logModel.Timestamp = time.Now().Unix()
		logModel.Create(s.db.GetDb())
	}

	return err
}

func (s *service) Create(ctx core.Context, createData *CreateData) error {
	model := user.NewModel()
	model.Email = createData.Email
	model.Username = createData.UserName
	model.MaturityTime = createData.MaturityTime
	data, err := model.GetUserByEmail(s.db.GetDb())
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		return err
	}
	if data.Email != "" {
		return errors.New("邮箱已存在")
	}
	data, err = model.GetUserByName(s.db.GetDb())
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		return err
	}
	if data != nil {
		return errors.New("用户名已存在")
	}
	model.Password = tools.MD5(createData.Password)
	model.ApiKey = tools.MD5(createData.UserName + model.Password + "TianShengDapp20240410")
	model.Status = 1
	model.Remark = createData.Remark
	id, err := model.Create(s.db.GetDb())

	if err == nil {
		userInfo := ctx.GetInfo("userInfo").(*userModel.User)
		logModel := operation_log.NewModel()
		logModel.FTable = "user"
		logModel.Type = "add"
		logModel.FId = id
		logModel.IpAddr = ctx.GetClientIP()
		logModel.AdminName = userInfo.Username
		logModel.Content = "新增用户:用户名[" + createData.UserName + "],邮箱:[" + createData.Email + "]"
		logModel.Timestamp = time.Now().Unix()
		logModel.Create(s.db.GetDb())
	}
	return err
}

func (s *service) Update(ctx core.Context, createData *CreateData) error {
	model := user.NewModel()
	model.Email = createData.Email
	model.Username = createData.UserName
	model.Id = createData.Id
	model.MaturityTime = createData.MaturityTime
	model.Remark = createData.Remark
	data, err := model.GetUserByEmail(s.db.GetDb())
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		return err
	}
	if data.Email != "" && data.Id != createData.Id {
		return errors.New("邮箱已存在")
	}

	data, err = model.GetUserByName(s.db.GetDb())
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		return err
	}
	if data != nil && data.Id != createData.Id {
		return errors.New("用户名已存在")
	}

	data, err = model.GetUserById(s.db.GetDb())
	if err != nil {
		return err
	}
	if data.Password != createData.Password {
		model.Password = tools.MD5(createData.Password)
	} else {
		model.Password = createData.Password
	}

	err = model.Update(s.db.GetDb())
	return err
}

func (s *service) UpdateLoginIp(ctx core.Context, id string) error {
	model := user.NewModel()

	model.Id = id
	model.LastLoginIP = ctx.GetClientIP()
	err := model.ChangeLoginIp(s.db.GetDb())
	return err
}
